/*
 * Peripheral Simulator (PSim)
 *
 * Copyright (c) 2008 Avadh Patel
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#ifndef PSIM_LIB_H
#define PSIM_LIB_H

#include <stdio.h>
#include <stdint.h>


#include <config.h>
#include <cpu.h>
#include <cpu-defs.h>
#include <message.h>
#include <stats.h>

enum DeviceType
{
  CPU,
  CACHE,
  PCI_BRIDGE,
  PCI_BUS,
  PCI_DEVICE,
  ISA_BRIDGE,
  PCI_IDE,
  PCI_NETWORK_CARD,
  NUM_TYPES
};

static const char* DeviceTypeNames[NUM_TYPES] = {
  "CPU",
  "CACHE",
  "PCI_BRIDGE",
  "PCI_BUS",
  "PCI_DEVICE",
  "ISA_BRIDGE",
  "PCI_IDE",
  "PCI_NETWORK_CARD",
};

typedef void DeviceInitFunction();

typedef struct RegisteredDevice RegisteredDevice;
struct RegisteredDevice
{
  enum DeviceType type;
  DeviceInitFunction* init;
};

//Every device will get registered with this simulator


//Flag: simulate (1->simulation enable, 0->simulation disable)
//extern int simulate;

uint64_t sim_get_clock();
void sim_enable();
void sim_disable();
int is_sim_enable();
void sim_inc_op_counter();
uint64_t sim_get_op_counter();


//Simulation Callback functions
//typedef void SimCBFunc(void *data);
typedef void SimCBFunc(Message* data);

typedef struct SimCB SimCB;
struct SimCB
{
  SimCBFunc* func;
  Message* arg_data;
  uint64_t time;
  SimCB* next;
};

void sim_insert_cb(SimCBFunc* _func, Message* _data, uint8_t delta);

void sim_reset_no_return();
void sim_set_no_return();
int sim_get_no_return();
void sim_do_callback();

void sim_reg_stats(struct stat_sdb_t* sdb);

#endif //PSIM_LIB_H
